﻿using System;
using BrainTechLLC.Silverlight.Controls;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Diagnostics;

namespace BrainTechLLC.Silverlight.ClientApplication
{
    public partial class GameThingTree : BaseDataVisualizer, ICollectionDataVisualizer, ICanRebindData<ObservableCollection<object>>
    {
        public event EventHandler<ObjectEventArgs<ObservableCollection<object>>> RebindingData;

        public override void SetVisualizedData(DataVisualizer vis, object o) { _counter = 0; ThingList = o as ObservableCollection<object>; base.SetVisualizedData(vis, o); }
        public Type VisualizeType { get { return typeof(object); } }
        public string VisualizerName { get { return "GameThingTree"; } }

        public static readonly DependencyProperty ThingListProperty = DependencyProperty.Register(
            "ThingList", typeof(ObservableCollection<object>), typeof(GameThingTree), new PropertyMetadata(null, new PropertyChangedCallback(ThingListChanged)));

        public static readonly DependencyProperty FilterTypeProperty = DependencyProperty.Register(
            "FilterType", typeof(Type), typeof(GameThingTree), new PropertyMetadata(null, new PropertyChangedCallback(FilterTypeChanged)));

        public ObservableCollection<object> ThingList
        {
            get { return (ObservableCollection<object>)GetValue(ThingListProperty); }
            set { SetValue(ThingListProperty, value); }
        }

        private static void ThingListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            HandleChange<ObservableCollection<object>>(d, e, (t, val) => t.ThingList = val);
        }

        public override string TitleText
        {
            get
            {
                return string.Format("{0} Items", ThingList.Count);
            }
        }

        public Type FilterType
        {
            get { return (Type)GetValue(FilterTypeProperty); }
            set { SetValue(FilterTypeProperty, value); }
        }

        private static void FilterTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            HandleChange<Type>(d, e, (t, val) => t.FilterType = val);
        }

        public static void HandleChange<T2>(DependencyObject d, DependencyPropertyChangedEventArgs e, Action<GameThingTree, T2> action)
        {
            d.HandleChange<GameThingTree, T2>(e, action, (t) => t.UpdateBindings());
        }

        public void FilterByType()
        {
            if (Parent != null && (Parent as Panel).Parent != null)
                Width = ((Parent as Panel).Parent as Control).Width;

            if (ThingList != null && FilterType != null)
                ThingList.RemoveWhere((o) => !FilterType.IsAssignableFrom(o.GetType()));
        }

        public override void UpdateBindings()
        {
            _counter = 0;
            FilterByType();
            BindList();
        }

        public void BindList()
        {
            _counter = 0;
            ObjectEventArgs<ObservableCollection<object>> eventArgs = new ObjectEventArgs<ObservableCollection<object>>(ThingList);

            if (RebindingData != null)
                RebindingData(this, eventArgs);

            if (eventArgs.obj == null || eventArgs.obj.Count <= 10)
            {
                pagerCanvas.Visibility = Visibility.Collapsed;
            }
            else
            {
                pagerCanvas.Visibility = Visibility.Visible;
                eventArgs.obj = (pager != null && eventArgs.obj != null) ? pager.GetCurrentPageCollection(eventArgs.obj) : eventArgs.obj;
            }
            lstGameThings.ItemsSource = eventArgs.obj;
        }

        public GameThingTree()
        {
            InitializeComponent();
        }

        void pager_EntryNumberChanged(object sender, ObjectEventArgsNonRef<int> e)
        {
            BindList();
        }

        void pager_ItemCountChanged(object sender, ObjectEventArgsNonRef<int> e)
        {
            BindList();
        }

        private void Grid_Loaded(object sender, RoutedEventArgs e)
        {
            FrameworkElement t = sender as FrameworkElement;
            t.StretchListBox();
        }

        private int _counter = 0;
        private void TextBlock_Loaded(object sender, RoutedEventArgs e)
        {
            _counter++;
            (sender as TextBlock).Text = _counter.ToString();
        }

        private void BaseDataVisualizer_Loaded(object sender, RoutedEventArgs e)
        {
            _counter = 0;
        }

        public static int _recurse;
        private void WrapPanel_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (_recurse > 0)
                return;

            _recurse = 1;
            try
            {
                WrapPanel wrap = sender as WrapPanel;
                double constDiff = 30;
                if (wrap.ActualHeight > constDiff)
                {
                    if (wrap.ActualHeight > scrollViewer.ActualHeight - constDiff)
                    {
                        wrap.Height = scrollViewer.ActualHeight - constDiff;
                    }
                    else if (wrap.ActualHeight == scrollViewer.ActualHeight - constDiff)
                    {
                    }
                    else if (!Double.IsNaN(wrap.Height))
                    {
                        wrap.Height = double.NaN;
                    }
                }
                else
                {
                    wrap.Height = double.NaN;
                }
            }
            catch (Exception ex) { Debug.WriteLine(ex.ToString()); }
            _recurse = 0;
        }

        private void editThing_RequestEditID(object sender, ObjectEventArgsNonRef<long> e)
        {
            OnRequestEditID(sender, e);
        }

        private void editThing_RequestGoLocation(object sender, ObjectEventArgs<LocationInt> e)
        {
            OnRequestGoToLocation(sender, e);
        }

        private void editThing_RequestEditGameLocation(object sender, ObjectEventArgs<LocationInt> e)
        {
            OnRequestGoToLocation(sender, e);
        }

    }
}
